LL_I3C_Init and LL_I3C_DeInit APIs migration ¶
The LL initialization and de-initialization functions previously available in the
stm32tnxx_ll_i3c.c
files
within HAL1 are no longer present in HAL2.
In HAL2, all LL C files (
stm32tnxx_ll_i3c.c) have been removed, leaving only the LL header files (
stm32tnxx_ll_i3c.h)
that contain static inline functions.
If users need to initialize or de-initialize I3C using the LL layer, they have two methods:
Utilize STM32CubeMX2 Code Generation: Rely on STM32CubeMX2 to generate code with the LL layer for I3C initialization and de-initialization.
- Replace manually the initialization and de-initialization functionsReplace the
LL_I3C_InitandLL_I3C_DeInitfunctions manually with equivalent sequences using the static inline functions provided in the
stm32tnxx_ll_i3c.hfile, tailored to their specific configuration and requirements.
- Replace manually the initialization and de-initialization functionsReplace the
This approach ensures that the initialization and de-initialization sequences are precisely addressing the given use case based on the LL static inline functions provided in the
stm32tnxx_ll_i3c.h
header file.
The sequences offer improved footprint optimization compared to the previous LL initialization functions found in
stm32tnxx_ll_i3c.c.
Related concept: Remove stm32tnxx_ll_ppp.c files
Method 1: Utilize STM32CubeMX2 Code Generation ¶
LL I3C configuration panel ¶
Create a new project with the STM32CubeMX2, then start the initialization and the main configuration.
LL I3C main features configuration ¶
Configure the I3C main features.
LL I3C advanced features configuration ¶
Configure the advanced I3C features.
GPIO configuration ¶
Configure GPIO pins.
DMA configuration ¶
Configure the DMA for data reception as needed.
DMA TX configuration ¶
DMA RX configuration ¶
DMA TC configuration ¶
NVIC configuration ¶
Configure the NVIC in case of an interrupt.
Generated I3C initialization sequences ¶
The I3C initialization sequence is generated in the
mx_i3c1_init
function in
mx_i3c1.c
file under
$YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.
Related concepts:
|
Topic |
Code Snippet HAL1 |
Code Snippet HAL2 |
|---|---|---|
|
Initialization and configuration sequence |
static void MX_I3C1_Init(void)
{
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Initializes the peripherals clock */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I3C1;
PeriphClkInitStruct.I3c1ClockSelection = RCC_I3C1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I3C1);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOF);
GPIO_InitStruct.Pin = LL_GPIO_PIN_5|LL_GPIO_PIN_15;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
LL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* I3C1 interrupt Init */
NVIC_SetPriority(I3C1_EV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(I3C1_EV_IRQn);
NVIC_SetPriority(I3C1_ER_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(I3C1_ER_IRQn);
/** I3C Initialization*/
LL_I3C_SetMode(I3C1, LL_I3C_MODE_CONTROLLER);
LL_I3C_SetDataHoldTime(I3C1, LL_I3C_SDA_HOLD_TIME_0_5);
LL_I3C_SetControllerActivityState(I3C1, LL_I3C_OWN_ACTIVITY_STATE_0);
LL_I3C_ConfigClockWaveForm(I3C1, 0x00774f77);
LL_I3C_SetCtrlBusCharacteristic(I3C1, 0x003100f8);
LL_I3C_DisableHJAck(I3C1);
/** Configure FIFO */
LL_I3C_SetRxFIFOThreshold(I3C1, LL_I3C_RXFIFO_THRESHOLD_1_4);
LL_I3C_SetTxFIFOThreshold(I3C1, LL_I3C_TXFIFO_THRESHOLD_1_4);
LL_I3C_DisableControlFIFO(I3C1);
LL_I3C_DisableStatusFIFO(I3C1);
/** Configure Controller */
LL_I3C_SetOwnDynamicAddress(I3C1, 0);
LL_I3C_EnableOwnDynAddress(I3C1);
LL_I3C_SetStallTime(I3C1, 0x00);
LL_I3C_DisableStallACK(I3C1);
LL_I3C_DisableStallParityCCC(I3C1);
LL_I3C_DisableStallParityData(I3C1);
LL_I3C_DisableStallTbit(I3C1);
LL_I3C_DisableHighKeeperSDA(I3C1);
/** Enable the selected I3C peripheral */
LL_I3C_Enable(I3C1);
}
|
I3C_TypeDef *mx_i3c1_init(void)
{
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I3C1);
LL_RCC_SetI3CClockSource(LL_RCC_I3C1_CLKSOURCE_PCLK1);
/* Set the controller mode */
LL_I3C_SetMode(I3C1, LL_I3C_MODE_CONTROLLER);
LL_I3C_ConfigClockWaveForm(I3C1, 0x120101U);
LL_I3C_SetBusCharacteristic(I3C1, 0xA002EU);
/* Set the FIFO configuration */
LL_I3C_ConfigCtrlFifo(I3C1, LL_I3C_RXFIFO_THRESHOLD_1_8, LL_I3C_TXFIFO_THRESHOLD_1_8, LL_I3C_CTRL_FIFO_NONE);
/* GPIO Clocks activation */
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
/* Configure IO output speed (Low, Medium, High or Very-High) */
LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_9, LL_GPIO_SPEED_FREQ_HIGH);
LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_8, LL_GPIO_SPEED_FREQ_HIGH);
/* Configure IO output type (Push-Pull or Open-Drain) */
LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_9 | LL_GPIO_PIN_8, LL_GPIO_OUTPUT_PUSHPULL);
/* Activate the Pull-up, Pull-down resistor, or No pull for the current IO */
LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_9, LL_GPIO_PULL_NO);
LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_8, LL_GPIO_PULL_NO);
/* Configure the Alternate Function in current IO */
LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_9, LL_GPIO_AF_2);
LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_8, LL_GPIO_AF_2);
/* Configure IO direction mode (Input, Output, Alternate or Analog) */
LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_9, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_8, LL_GPIO_MODE_ALTERNATE);
/* Enable the Event interrupt for I3C1 */
NVIC_SetPriority(I3C1_EV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));
NVIC_EnableIRQ(I3C1_EV_IRQn);
/* Enable the Error interrupt for I3C1 */
NVIC_SetPriority(I3C1_ERR_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));
NVIC_EnableIRQ(I3C1_ERR_IRQn);
return I3C1;
}
|
Method 2: Manually replace the initialization and de-initialization functions ¶
LL_I3C_Init() API migration ¶
According to the use-case, implement the precise sequence call based on the LL static inline functions provided in
the
stm32tnxx_ll_i3c.h
header file.
|
HAL1 |
HAL2 |
|---|---|
|
Case of I3C in mode CONTROLLER LL_I3C_InitTypeDef i3c_InitStruct;
i3c_InitStruct.CtrlBusCharacteristic.SDAHoldTime = LL_I3C_SDA_HOLD_TIME_0_5;
i3c_InitStruct.CtrlBusCharacteristic.WaitTime = LL_I3C_OWN_ACTIVITY_STATE_0;
i3c_InitStruct.CtrlBusCharacteristic.SCLPPLowDuration = 1U;
i3c_InitStruct.CtrlBusCharacteristic.SCLI3CHighDuration = 2U;
i3c_InitStruct.CtrlBusCharacteristic.SCLODLowDuration = 3U;
i3c_InitStruct.CtrlBusCharacteristic.SCLI2CHighDuration = 4U;
i3c_InitStruct.CtrlBusCharacteristic.BusFreeDuration = 5U;
i3c_InitStruct.CtrlBusCharacteristic.BusIdleDuration = 6U;
i3c_InitStruct.TgtBusCharacteristic.BusAvailableDuration = 7U;
LL_I3C_Init(I3C1, &i3c_InitStruct, LL_I3C_MODE_CONTROLLER);
|
LL_I3C_SetMode(I3C1, LL_I3C_MODE_CONTROLLER);
uint32_t waveform_value = (1U
| (2U << I3C_TIMINGR0_SCLH_I3C_Pos)
| (3U << I3C_TIMINGR0_SCLL_OD_Pos)
| (4U << I3C_TIMINGR0_SCLH_I2C_Pos));
LL_I3C_ConfigClockWaveForm(I3C1, waveform_value);
uint32_t timing_value = (LL_I3C_SDA_HOLD_TIME_0_5
| LL_I3C_OWN_ACTIVITY_STATE_0
| (5U << I3C_TIMINGR1_FREE_Pos)
| 6U);
LL_I3C_SetCtrlBusCharacteristic(I3C1, timing_value);
|
|
Case of I3C in mode TARGET LL_I3C_InitTypeDef i3c_InitStruct;
i3c_InitStruct.CtrlBusCharacteristic.SDAHoldTime = LL_I3C_SDA_HOLD_TIME_0_5;
i3c_InitStruct.CtrlBusCharacteristic.WaitTime = LL_I3C_OWN_ACTIVITY_STATE_0;
i3c_InitStruct.CtrlBusCharacteristic.SCLPPLowDuration = 1U;
i3c_InitStruct.CtrlBusCharacteristic.SCLI3CHighDuration = 2U;
i3c_InitStruct.CtrlBusCharacteristic.SCLODLowDuration = 3U;
i3c_InitStruct.CtrlBusCharacteristic.SCLI2CHighDuration = 4U;
i3c_InitStruct.CtrlBusCharacteristic.BusFreeDuration = 5U;
i3c_InitStruct.CtrlBusCharacteristic.BusIdleDuration = 6U;
i3c_InitStruct.TgtBusCharacteristic.BusAvailableDuration = 7U;
LL_I3C_Init(I3C1, &i3c_InitStruct, LL_I3C_MODE_TARGET);
|
LL_I3C_SetMode(I3C1, LL_I3C_MODE_TARGET);
LL_I3C_SetTgtBusCharacteristic(I3Cx, 7U);
|
LL_I3C_DeInit() API migration ¶
According to the used I3C1, Implement the precise calls to
LL_APB1_GRP1_ForceReset()
and
LL_APB1_GRP1_ReleaseReset()
|
HAL1 |
HAL2 |
|---|---|
LL_I3C_DeInit(I3C1)
|
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I3C1);
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I3C1);
|